package com.xiongjie.eb;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xiongjie.impl.IPerson;
import com.xiongjie.impl.IPersonImpl;
import com.xiongjie.util.PgWrapper;
import io.vertx.config.ConfigRetriever;
import io.vertx.config.ConfigRetrieverOptions;
import io.vertx.config.ConfigStoreOptions;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import io.vertx.serviceproxy.ServiceBinder;

public class PersonEventBusVerticle extends AbstractVerticle {

    /**
     * 1.获取数据库操作的配置文件
     * @return
     */
    public String sqlTemplatePath() {
        return String.format("sql/%s.yml", "xiongjie");
    }

    /**
     * 2.配置文件,读取具体的sql文件
     * @return
     */
    protected String configPath() {
        return String.format("%s-config.yml", "xiongjie");
    }

    /**
     * 3.必须要添加验证代码
     * @param config
     * @return
     */
    private Future<Void> validateJson(JsonObject config) {
        final Future<Void> future = Future.future();
        return future;
    }

    /**
     * 4.初始化pg,并绑定到vertx的eventbus上，使用代理类操作
     * @param v
     * @return
     */
    protected Future<Void> initialize(Void v) {
        final JsonObject eventbusConfig = config().getJsonObject("eventbus");
        final JsonObject pgConfig = eventbusConfig.getJsonObject("pg", new JsonObject());

        return PgWrapper
            .createInstance(vertx, pgConfig, sqlTemplatePath())
            .compose(pg -> {
                new ServiceBinder(vertx)
                        .setAddress("xiongjie")
                        .register(IPerson.class, new IPersonImpl(pg));
                return Future.succeededFuture();
            });
    }

    /**
     * 5.真正的初始化pg,读取配置文件,主要是数据库的地址和用户名密码
     * @param startFuture
     */
    @Override
    public void start(Future<Void> startFuture) {
        ConfigStoreOptions fileStore = new ConfigStoreOptions()
                .setType("file")
                .setOptional(true)
                .setFormat("yaml")
                .setConfig(new JsonObject().put("path", configPath()));

        ConfigStoreOptions jsonStore = new ConfigStoreOptions()
                .setType("json")
                .setOptional(true)
                .setConfig(super.config());

        ConfigRetrieverOptions options = new ConfigRetrieverOptions()
                .setScanPeriod(0)
                .addStore(fileStore)
                .addStore(jsonStore);

        ConfigRetriever.getConfigAsFuture(ConfigRetriever.create(vertx, options))
                .compose(this::validateJson)
                .compose(this::initialize)
                .setHandler(ar -> {
                    if (ar.succeeded()) {
                        startFuture.complete();
                    } else {
                        startFuture.fail(ar.cause());
                    }
                });
    }
}
